闲话 22.11.16
闲话
今天给我整了个好活 普通三维偏序的 解法
那就要问了,形如 的加强版三维偏序有没有什么 的做法
如果有人搞出来了可以在这提交(
有什么好题当社论题材吗?
最近想写ARC148F来着
啊对了今天放冠世一战了!好听!
杂题
AGC056B
给定整数 以及 对整数。第 对整数为 。请输出可以通过如下方式生成的整数序列 的个数。答案对 取模。
生成方式:
- 取排列 ,满足其为一个 至 的排列。
- 对于任意 的 ,令 为 中最大值对应的下标。即 。
。
为啥这场 B 比 C 难啊
C 是个 2481 比这一段的 C 都简单 B 是个 nmd 3339 比这一段的 C 都难
A 是个 sb 构造,暂且不表
同一个 可能对应多个 ,因此这样计数比较困难。
考虑反过来计数。
对于给定的 ,我们将按照以下的方式构造 :
- 令 。
- 我们从 开始依次递减地考虑每个值 。对于每个值,我们找到 能放的最左侧的位置,放进去。
计数可以通过这种方式生成的 。
设当前最值为 。我们首先确定下标 ,使得 。对于所有包含 的区间 ,有 。删除这些包含 的区间后,我们可以分别考虑位于 左右两侧的区间。由于 为最左侧的可以放 的位置,右侧的数均小于左侧的数,这部分是和原问题等价但规模更小的子问题。
现在考虑左侧。我们令 为 左侧最大元素对应的下标。有:必定存在一个左侧区间同时包含 和 。
考虑反证。如果左侧没有区间同时包含 和 ,那我们可以令 ,这必定是更优且满足要求的。这与假设矛盾,因此必定存在同时包含 和 的左侧区间。
因此,左侧区间所填的数的最大值必定大于等于 。
考虑区间 dp。我们设 为 区间满足最大值大于等于 的方案数。可以通过枚举中点以及预处理区间最大值的方式转移。转移时加入后缀和即可快速得到最终答案。
时间复杂度 。
code
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int,int>;
template <typename T> void get(T & x) {
x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x);
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
template <typename T1, typename T2> T1 min(T1 a, T2 b) { T1 _b = static_cast<T1>(b); return a < b ? a : b; }
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
const int N = 5e2 + 10;
const int mod = 998244353;
const int inv2 = (mod + 1) >> 1;
template <typename T1, typename T2> T1 add(T1 a, T2 b) { return (a += b) >= mod ? a - mod : a; }
template <typename T1, typename ...Args> T1 add(T1 a, Args ... b) { return add(a, add(b...)); }
struct FastMod { int m; ll b; void init(int _m) { m = _m; if (m == 0) m = 1; b = ((lll)1<<64) / m; } FastMod(int _m) { init(_m); } int operator() (ll a) {ll q = ((lll)a * b) >> 64; a -= q * m; if (a >= m) a -= m; return a; } } Mod(mod);
int mul(int a, int b) { return Mod(1ll * a * b); } template <typename ...Args> int mul(int a, Args ...b) { return mul(a, mul(b...)); }
template <typename T1, typename T2> T1 qp(T1 a, T2 b) { T1 ret = 1; for (; b > 0; a = mul(a, a), b >>= 1) if (b & 1) ret = mul(ret, a); return ret; }
int n, m, f[N][N][N], g[N][N][N];
pii v[N * (N - 1) >> 1];
int main() {
get(n, m); rep(i,1,m) get(v[i].first, v[i].second);
rep(i,0,n+1) rep(j,0,n+1) rep(k,0,n+1) g[i][j][k] = n + 1;
rep(i,1,m) rep(k,v[i].first,v[i].second) g[v[i].first][v[i].second][k] = min(g[v[i].first][v[i].second][k], v[i].first);
pre(l,n,1) rep(r,l+1,n) rep(k,l,r) g[l][r][k] = min( { g[l][r][k], g[l+1][r][k], g[l][r-1][k] } );
rep(l,1,n+1) rep(k,1,n+1) f[l][l-1][k] = 1;
pre(l,n,1) rep(r,l,n) pre(k,r,l) f[l][r][k] = add(f[l][r][k + 1], mul(f[l][k - 1][g[l][r][k]], f[k + 1][r][k + 1]));
cout << f[1][n][1] << '\n';
}
你需要构造一个长度为 、由 组成的字符串,同时需要满足 个条件。第 个条件由两个整数 给出,表示字符串位于 区间的字符必须是相同数量的 和 。
请输出满足所有条件且字典序最小的字符串。可以证明在题设条件下总存在至少一个字符串满足所有条件。
直接做不好做,考虑将条件转化。令 为 中 的个数减去 的个数。
容易发现,想要最小化原串的字典序,其实就是让 尽可能多,也就是让 尽可能大。这就转化为如何 的字典序最大。
我们发现,给定的条件 可以表述为 ,因为 段中 个数是相等的,体现在 上就是 段有 的贡献。
同时根据定义可得 。这与 等价。
列出我们已知的条件:
我们需要使字典序最大,这启发我们采用差分约束系统求解本题。
对 条件建 ,边权为 的双向边;对 条件建 ,边权为 的双向边。
由于边权的特殊性,我们可以通过 01bfs 求解所有 。这给出了构造方案。
总时间复杂度 。
code
#include <bits/stdc++.h>
using namespace std;
template <typename T> void get(T & x) {
x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x);
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
const int N = 1e6 + 10;
int n, m, l, r;
vector <pair<int,int> > g[N];
int dis[N];
deque<int> que;
void bfs(int st) {
memset(dis, -1, sizeof dis);
dis[st] = 0; que.push_back(st);
while (que.size()) {
int u = que.front(); que.pop_front();
for (auto [v, w] : g[u]) {
if (dis[v] == -1) {
dis[v] = dis[u] + w;
if (w == 0) que.push_front(v);
else que.push_back(v);
}
}
}
}
int main() {
get(n, m);
rep(i,1,m) get(l, r), g[r].emplace_back(l - 1, 0), g[l - 1].emplace_back(r, 0);
rep(i,1,n) g[i - 1].emplace_back(i, 1), g[i].emplace_back(i - 1, 1);
bfs(0);
rep(i,1,n) cout << (dis[i] < dis[i - 1]);
}
给出一个字母阵 ,再给出一个部分字母没有确定的询问阵 ,求出左上角为位置 时能否匹配 ,输出 矩阵表示答案。
。
昨天 WintersRain 发了个博客 vp 390 (Div. 2)
然后我看着他们没写这题 然后水一下
首先考虑朴素的 如何实现。令 为 的矩阵, 为 的矩阵。
memset(ans, true, sizeof(ans));
for (int k = 1; k <= r; ++ k) for (int l = 1; l <= c; ++ l) if (T[k][l] != '?')
for (int i = 1; i <= n; ++ i) for (int j = 1; j <= m; ++ j)
ans[(i - k + n) % n][(j - l + m) % m] &= (T[k][l] == P[i][j]);
发现最终我们需要对答案数组的整行进行有条件的与操作。这使我们想到使用 bitset 优化进程。
对 矩阵中每行使用 26 个 bitset ,第 位保存 是否存在于这一位。我们发现朴素实现的第 层循环可以使用 bitset 表示。
因此采用 bitset 优化后可以做到 ,足以通过本题。
本题的思想类似于 CF914F,二者都是通过 bitset 进行带通配符的字符串匹配。
同时,本题还有采用多项式的解法,方式形如本题。时间复杂度为 。由于常数过大,在实际测评中远不如 bitset 做法优秀。
以及这题 可能远大于 ,注意直接取模。
code
#include <bits/stdc++.h>
using namespace std;
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
const int N = 400 + 10;
int n, m, r, c;
char str[N];
bitset<N> ans[N], mask[26][N];
int main() {
ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
cin >> n >> m;
rep(i,1,n) {
ans[i].set();
cin >> str + 1;
rep(j,1,m) mask[str[j]-'a'][i].set(j);
} cin >> r >> c;
rep(i,1,r) {
cin >> str + 1;
rep(j,1,c) if (str[j] != '?') rep(k,1,n)
ans[(k - i % n + n) % n + 1] &= (mask[str[j] - 'a'][k] >> (j - 1 + m) % m) | (mask[str[j] - 'a'][k] << m - (j - 1 + m) % m);
}
rep(i,1,n) {
rep(j,1,m) cout << ans[i][j];
cout << '\n';
}
}
以下是博客签名,与正文无关。
请按如下方式引用此页:
本文作者 joke3579,原文链接:https://www.cnblogs.com/joke3579/p/chitchat221116.html。
遵循 CC BY-NC-SA 4.0 协议。
请读者尽量不要在评论区发布与博客内文完全无关的评论,视情况可能删除。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)